package com.lhj.security.config.security;

import com.lhj.security.config.filter.JwtAuthenticationFilter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * @Author lhj
 * @Date 2024/12/25 15:21
 */
@Configuration
public class SecurityConfig {

    private final String[] matchers = new String[]{
            "/login", "/registry",
    };

    @Resource
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //禁用csrf
        http.csrf(csrf -> csrf.disable()).httpBasic(withDefaults());
        // 禁用HTTP响应头
        http.headers((headersCustomizer) -> {
                    headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
                })
                //认证失败处理类
                .exceptionHandling(exception -> exception.authenticationEntryPoint(new JwtAuthenticationEntryPoint()))
                // 禁用Session
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                // 禁用表单登录
                .formLogin().disable();
        // 配置权限
        http.authorizeHttpRequests((requests) -> {
                    //配置不需要拦截的接口
                    requests.requestMatchers(matchers).permitAll()
                            // 跨域请求会先进行一次options请求，这里需要放行
                            .requestMatchers(HttpMethod.OPTIONS).permitAll()
                            // 其他请求都需要认证
                            .anyRequest()
                            // 认证
                            .authenticated();

                }

        );

        // 添加JWT过滤器
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);


        // 基础自定义表单登陆
        // http.authorizeRequests(authorize -> authorize.anyRequest().authenticated());
        // http.formLogin(form -> form.loginPage("/login").permitAll());
        return http.build();
    }


    @Bean
    public AuthenticationManager authenticationManager(UserDetailsService userDetailsService) {
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
        return new ProviderManager(daoAuthenticationProvider);
    }

    //基于内存创建用户
    /*@Bean
    public UserDetailsService users() {
        User.UserBuilder users = User.withDefaultPasswordEncoder();
        UserDetails user = users.username("user").password("password").roles("USER").build();

        UserDetails admin = users.username("admin").password("password").roles("USER", "ADMIN").build();
        return new InMemoryUserDetailsManager(user, admin);
    }*/

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
